在多種 3D 物理引擎裡,決定使用同樣基於 js 所開發,學習成本相對較低且對新手較友善的 Cannon.js 做為開發工具
Github
與之前的函式庫相同需要先在 ejs 處匯入
<script src="https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js"></script>
與 Three.js 需要先建立 scene 相同,Cannon.js 也需要先建立 World
// 建立Cannon世界
world = new CANNON.World()
// 設定重力場為 y 軸 -9.8 m/s²
world.gravity.set(0, -9.8, 0)
建立球剛體
var radius = 1
sphereBody = new CANNON.Body({
mass: 5, //質量 kg
position: new CANNON.Vec3(0, 10, 0), // m
shape: new CANNON.Sphere(radius),
})
world.add(sphereBody)
建立平台
var groundBody = new CANNON.Body({
mass: 0, // mass = 0 使物體靜止
})
var groundShape = new CANNON.Plane()
groundBody.addShape(groundShape);
world.add(groundBody)
// setFromAxisAngle 地板沿著X軸轉90度
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2)
建立球網格,建立完的剛體需要加上網格才能看到實體
let sphereGeometry = new THREE.SphereGeometry(1, 32, 32)
let sphereMaterial = new THREE.MeshStandardMaterial({ color: 0x33aaaa })
sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.castShadow = true
scene.add(sphere)
建立地板網格
let groundGeometry = new THREE.PlaneGeometry(30, 30, 30)
let groundMaterial = new THREE.MeshLambertMaterial({
color:0x505050,
side: THREE.DoubleSide,
})
let ground = new THREE.Mesh(groundGeometry, groundMaterial)
ground.rotation.x = -Math.PI / 2
ground.receiveShadow = true
scene.add(ground)
渲染畫面,將 cannon 世界中的剛體位置持續更新,同步至網格位置
function render() {
world.step(fixedTimeStep)
// 複製剛體位址到物體位置
sphere.position.copy(sphereBody.position)
sphere.quaternion.copy(sphereBody.quaternion)
console.log("Sphere y position: " + sphereBody.position.y);
statsUI.update()
cameraControl.update()
requestAnimationFrame(render)
renderer.render(scene, camera)
}
Day14 Demo | Github
就可以看到掉落的球體了